﻿using OnHook.Business.Dto.Order;
using OnHook.Business.IServices;
using OnHook.Business.IServices.Common;
using OnHook.Business.IServices.Pay;
using OnHook.Business.Options;
using OnHook.Business.Services.Common;
using OnHook.Business.Vo.Order;
using OnHook.Business.Vo.UserInfo;
using OnHook.Common;
using OnHook.Common.Extension;
using OnHook.Domain;
using OnHook.Domain.Entities;
using OnHook.Domain.Enums;
using OnHook.Framework.Exceptions;
using OnHook.Framework.Extensions;
using OnHook.Framework.Ioc;
using OnHook.Common.UtilsHelper;
using EasyTool;
using Mapster;
using Serilog;
using SqlSugar;

namespace OnHook.Business.Services
{
    /// <summary>
    /// 订单服务
    /// </summary>
    public class OrderService(ISqlSugarClient db
        , IOrderLogService orderlogService
        , IServiceProvider serviceProvider
        , IJwtService jwtService
        , IRedisCacheService redisCacheService
        ) : IOrderService, IScoped
    {
        private readonly ISqlSugarClient _db = db;
        private readonly IOrderLogService _orderlogService = orderlogService;
        private readonly IServiceProvider _serviceProvider = serviceProvider;
        private readonly IJwtService _jwtService = jwtService;
        private readonly IRedisCacheService _redisCacheService = redisCacheService;

        /// <summary>
        /// 购买商品
        /// </summary>
        /// <param name="params"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        public async Task<CreateOrderResultVo<IDictionary<string, string>>> BuyGoodsAsync(CreateOrderDto @params)
        {
            var goods = await _db.Queryable<Goods>().Includes(x => x.Details).FirstAsync(x => x.Id == @params.GoodsId);
            if (goods.IsNull()) throw new BusinessException("商品不存在");
            Order order = await CreateOrder(@params, goods);
            order.OrderType = EnumOrderType.BuyProduct;
            order.Ext1 = goods.ToJson(true);
            //if (await _repository.AddEntityAsync(order))
            if (await _db.InsertNav(order).Include(x => x.Details).ExecuteCommandAsync())
            {
                await _orderlogService.AddOrderLogAsync(order, "创建订单成功过");
                return await CreatePayOrder(order, @params.Platform);
            }
            else
            {
                throw new BusinessException("创建订单失败");
            }
        }
        /// <summary>
        /// 创建订单
        /// </summary>
        /// <param name="params"></param>
        /// <param name="goods"></param>
        /// <returns></returns>
        public async Task<Order> CreateOrder(CreateOrderDto @params, Goods goods)
        {
            LoginUserVo? userInfo = _jwtService.GetCurrentUser() ?? throw new BusinessException("用户未登录");
            var appsetting = await _redisCacheService.GetAppSettingAsync<AppSettingOption>();
            var orderDebug = appsetting?.OrderDebug ?? false;
            var oderTimeSpan = appsetting?.OrderTimeSpan ?? 3;
            var isProfitSharing = appsetting?.IsProfitSharing ?? false;
            var preOrder = await _db.Queryable<Order>().Where(x => x.UserId == userInfo.Id && x.HasPaid && x.OrderType == @params.OrderType).OrderBy(x => x.CreateTime).FirstAsync();
            if (preOrder.IsNotNull())
            {
                int timespan = (int)(DateTime.Now - preOrder.CreateTime).TotalSeconds;
                if (timespan < oderTimeSpan)
                {
                    throw new BusinessException($"您下单太过频繁，请等待{oderTimeSpan - timespan}秒后再试");
                }
            }
            int payAmount = orderDebug ? 1 : goods.BuyPrice;

            var order = new Order()
            {
                Id = IdHelper.NextId(),
                CreateTime = DateTime.Now,
                DeleteStatus = false,
                OrderAmount = payAmount,
                PayableAmount = payAmount,
                OrderId = CreateOrderId(@params.Platform),
                GoodsId = @params.GoodsId,
                GoodsName = goods?.GoodsName ?? "",
                UserId = userInfo.Id,
                OrderType = @params.OrderType,
                OrderTypeName = @params.OrderType.GetDescription(),
                PayType = @params.PayType,
                PayTypeName = @params.PayType.GetDescription(),
                Ip = @params.IP,
                HasPaid = false,
                IsDebug = orderDebug,
                OpenId = userInfo.OpenInfos.FirstOrDefault(c => c.Platform == @params.Platform.ToString())?.OpenId ?? "",
                IsProfitSharing = isProfitSharing,
            };
            order.Details = goods?.Details?.Select(gd =>
            {
                var od = gd.Adapt<OrderDetail>();
                od.OrderId = order.Id;
                od.Id = IdHelper.NextId();
                return od;
            }).ToList();
            return order;
        }

        public async Task<Order> ExcuteOrderPayCallBack(string content, EnumPlatform platform)
        {
            Log.Information("接收到支付通知消息：" + content);
            //IPayService payService = _serviceProvider.GetNamedService<IPayService>(platform.ToString()); //
            return null;
        }
        /// <summary>
        /// 统一下单
        /// </summary>
        /// <param name="order"></param>
        /// <param name="platform"></param>
        /// <returns></returns>
        public async Task<CreateOrderResultVo<IDictionary<string, string>>> CreatePayOrder(Order order, EnumPlatform platform)
        {
            CreateOrderResultVo<IDictionary<string, string>> createOrderResult;
            if (order.PayableAmount > 0)
            {
                IPayService payService = _serviceProvider.GetNamedService<IPayService>(platform.ToString()); //IocManager.Instance.Resolve<IPayService>(platform.ToString());
                createOrderResult = await payService.CreateOrderAsync(order);
                createOrderResult.PayType = order.PayType;
            }
            else
            {
                throw new BusinessException("订单金额为0");
            }

            if (createOrderResult.IsNotNull())
            {
                createOrderResult.Id = order.Id;
                createOrderResult.OrderId = order.OrderId;
            }
            return createOrderResult;
        }


        /// <summary>
        /// 生成订单
        /// </summary>
        /// <param name="platform"></param>
        /// <returns></returns>
        private static string CreateOrderId(EnumPlatform platform)
        {
            string prefix = "wx";
            switch (platform)
            {
                case EnumPlatform.Wechat:
                    prefix = "wx";
                    break;
                case EnumPlatform.Alipay:
                    prefix = "al";
                    break;
            }
            string orderNo = $"{prefix}{DateTime.Now:yyyyMMddHHmmss}{RandomUtil.RandomDigitString(4)}";
            return orderNo;
        }
    }
}
